package pt.isel.pdm.ouryamba;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.SystemClock;

/**
 * Service responsible to periodically update the database.
 * */
public class AutomaticTimelineUpdateService extends Service implements Runnable
{
	public static final String ID = "AutomaticTimelineUpdateService";
	private static final String WORKER_THREAD_NAME = ID + "_worker_thread";
	private Thread worker_thread;
	private General app;
	private final Integer CONST_ONE_MIN_IN_MILIS = 60000;
	private Intent updaterIntent;

	/**
	 * Since this is not a bound service it returns null.
	 * */
	@Override
	public IBinder onBind(Intent intent) 
	{
		return null;
	}

	/**
	 * Starts the worker thread.
	 * */
	@Override
	public void onCreate() 
	{
		super.onCreate();
		app = (General) getApplication();
		worker_thread = new Thread(this);
		worker_thread.setName(WORKER_THREAD_NAME);
		worker_thread.start();
		app.log(ID + " Service created.");
	}

	/**
	 * Interrupts the worker thread if it wasn't already interrupted.
	 * */
	@Override
	public void onDestroy() 
	{
		if(!worker_thread.isInterrupted())
		{
			worker_thread.interrupt();
			worker_thread = null;
		}
		app.log(ID + " Service destroyed.");
		super.onDestroy();
	}
	
	/**
	 * Is the behavior of the worker thread which is responsible for the automatic updates.</br>
	 * 
	 * This thread will wait until there is network connectivity so it wont waste resources.
	 * It only work according to the preference set in the preferences by the user.
	 * For each interval settled it send an intent to the {@code TimelinePullService} so that one could perform
	 * the update and write into database (and also notify waiters).
	 * 
	 * @see General#hasNetworkConnection()
	 * @see General#log(String)
	 * @see General#getAutomaticUpdate()
	 * @see General#getAutomaticUpdateInterval()
	 * @see General#logException(Exception)
	 * */
	@Override
	public void run() 
	{
		app.log(WORKER_THREAD_NAME + ".run(): Automatic update started.");
		TimelineActivity tma;
		int sleepTime;
		try
		{
			while(true)
			{
				while(!app.hasNetworkConnection())
				{
					synchronized (app.waiterForNetworkLock) 
					{
						app.log(WORKER_THREAD_NAME + ".run(): Going to wait for network.");
						app.waiterForNetworkLock.wait();
						app.log(WORKER_THREAD_NAME + ".run(): Waking with network.");
					}	
				}
				if(app.getAutomaticUpdate() && app.hasNetworkConnection())
				{
					if(updaterIntent == null)
					{
						updaterIntent = new Intent(getApplicationContext(), TimelinePullService.class);
					}
					tma = app.timelineActivity.get();
					if(tma != null && tma.hasWindowFocus())
					{
						app.waiter.Wait(tma, tma);
					}
					startService(updaterIntent);
					sleepTime = app.getAutomaticUpdateInterval()*CONST_ONE_MIN_IN_MILIS;
					SystemClock.sleep(sleepTime);
				}
			}
		}
		catch(InterruptedException e)
		{
			app.log(WORKER_THREAD_NAME + ".run(): Thread interrupted.");
		}
		catch(Exception e)
		{
			app.log(WORKER_THREAD_NAME + ".run(): Exception thrown.");
			app.logException(e);
		}
		app.log(WORKER_THREAD_NAME + ".run(): Automatic update stopped.");
	}

}
